package sample.batch.faulttolerant;

import sample.batch.helloworld.Person;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder;
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;

/**
 * @date 2020/12/15
 */
@SpringBootApplication
@EnableBatchProcessing
public class FaultTolerantApplication {

	public static void main(String[] args) {
		SpringApplication.run(FaultTolerantApplication.class, args);
	}

	@Autowired
	public JobBuilderFactory jobBuilderFactory;

	@Autowired
	public StepBuilderFactory stepBuilderFactory;

	@Bean
	public FlatFileItemReader<Person> reader() {
		return new FlatFileItemReaderBuilder<Person>()
				.name("personItemReader")
				.resource(new ClassPathResource("sample-data.csv"))
				.delimited()
				.names(new String[]{"firstName", "lastName"})
				.fieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {{
					setTargetType(Person.class);
				}})
				.build();
	}

	@Bean
	public ItemProcessor<Person, Person> processor() {
		return item -> item;
	}

	@Bean
	public ItemWriter<Person> writer() {
		return items -> {
			System.out.println(items);
			for (Person person : items) {
				if (person.getFirstName().equals("Justin")) {
					throw new RuntimeException("Mock");
				}
			}
		};
	}

	@Bean
	public Job skipJob2(Step step1) {
		return jobBuilderFactory.get("skipJob5")
				.start(step1)
				.build();
	}

	@Bean
	public Step step3() {
		return stepBuilderFactory.get("step3")
				.<Person, Person> chunk(2)
				.reader(reader())
				.processor(processor())
				.writer(writer())
				.faultTolerant()
				.skip(Exception.class)
				.skipLimit(10)
				.retry(Exception.class)
				.retryLimit(10)
				.build();
	}
}
